#include"client.h"

void getsCommand(client_task_t * task) {

    //服务端文件不存在
    CmdType x;
    recvn(task->peerfd, &x, sizeof(x));
    if (x == -1) {
        //文件不存在
        printf("File does not exist.\n");
    } else {
    //此时服务端存在该文件
    //此时文件名存储在小火车的buff中
    //如果文件不存在,创建文件
    //如果文件存在，断点续传
    //根据文件名打开/创建文件
    char filename[100] = {0};
    strcpy(filename, task->train.buff);
    int wfd = open(filename, O_CREAT | O_RDWR, 0644);
    if (wfd == -1) {
        error(1, errno, "open");
    }

    //获取此时文件长度，进行断点重传
    //将此时的文件长度发送给对方
    struct stat st;
    memset(&st, 0, sizeof(st));
    fstat(wfd, &st);
    sendn(task->peerfd, &st.st_size, sizeof(st.st_size));

    //接收文件长度
    off_t length = 0;
    recvn(task->peerfd, &length, sizeof(length));
    printf("file length: %ld\n", length);

    //续传的长度
    off_t clen = length - st.st_size;
    //最后接收文件内容
    //判断文件长度是否大于100M如果大于100M，采用零拷贝技术
    //避免磁盘空间不够，可以先创建一个文件空洞

    //创建一条管道
    int fds[2];
    pipe(fds);

    //大文件断点续传
    if (clen > 100 * 1024 * 1024) {
        ftruncate(wfd, length);
        //4将文件偏移到文件
        if(lseek(wfd, st.st_size, SEEK_SET) == -1){
            error(1,errno,"lseek ");
        }

        off_t curSize = 0;
        int ret = 0;
        while (curSize < clen) {
            ret = splice(task->peerfd, NULL, fds[1], NULL, 4096, SPLICE_F_MORE);
            if (ret == 0) {
                break;
            }
            ret = splice(fds[0], NULL, wfd, NULL, ret, SPLICE_F_MORE);
            curSize += ret;
        }

    } else {
        while(1) {
            //接收长度
            int len;
            int ret = recvn(task->peerfd, &len, sizeof(len));//先接长度
            if (len == 0) {
                break;
            }

            //接收占位的类型的值
            CmdType x;
            recvn(task->peerfd,&x,sizeof(x));

            //接收文件内容
            char buff[1000] = {0};
            ret = recvn(task->peerfd, buff, len);

            //最后再写入本地
            write(wfd, buff, ret);
        }//while
     }
    close(wfd);

    //告诉用户端传输成功
    printf("recv %s over\n", task->train.buff);
  }//这个是文件存在时的else
}
